1 From ede965fd555ac2536cf651893a998dbfd8e57b86 Mon Sep 17 00:00:00 2001
2 From: Jonas Jelonek <jelonek.jonas@gmail.com>
3 Date: Sun, 31 Aug 2025 10:04:48 +0000
4 Subject: [PATCH] i2c: rtl9300: remove broken SMBus Quick operation support
6 Remove the SMBus Quick operation from this driver because it is not
7 natively supported by the hardware and is wrongly implemented in the
10 The I2C controllers in Realtek RTL9300 and RTL9310 are SMBus-compliant
11 but there doesn't seem to be native support for the SMBus Quick
12 operation. It is not explicitly mentioned in the documentation but
13 looking at the registers which configure an SMBus transaction, one can
14 see that the data length cannot be set to 0. This suggests that the
15 hardware doesn't allow any SMBus message without data bytes (except for
16 those it does on it's own, see SMBus Block Read).
18 The current implementation of SMBus Quick operation passes a length of
19 0 (which is actually invalid). Before the fix of a bug in a previous
20 commit, this led to a read operation of 16 bytes from any register (the
21 one of a former transaction or any other value.
23 This caused issues like soft-bricked SFP modules after a simple probe
24 with i2cdetect which uses Quick by default. Running this with SFP
25 modules whose EEPROM isn't write-protected, some of the initial bytes
26 are overwritten because a 16-byte write operation is executed instead of
27 a Quick Write. (This temporarily soft-bricked one of my DAC cables.)
29 Because SMBus Quick operation is obviously not supported on these
30 controllers (because a length of 0 cannot be set, even when no register
31 address is set), remove that instead of claiming there is support. There
32 also shouldn't be any kind of emulated 'Quick' which just does another
33 kind of operation in the background. Otherwise, specific issues occur
34 in case of a 'Quick' Write which actually writes unknown data to an
37 Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
38 Cc: stable@vger.kernel.org # v6.13+
39 Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
40 Tested-by: Sven Eckelmann <sven@narfation.org>
41 Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
42 Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
43 Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
44 Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
45 Link: https://lore.kernel.org/r/20250831100457.3114-4-jelonek.jonas@gmail.com
47 diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
48 index 2b3e80aa1bdf..9e1f71fed0fe 100644
49 --- a/drivers/i2c/busses/i2c-rtl9300.c
50 +++ b/drivers/i2c/busses/i2c-rtl9300.c
51 @@ -225,15 +225,6 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
55 - case I2C_SMBUS_QUICK:
56 - ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
59 - ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
65 if (read_write == I2C_SMBUS_WRITE) {
66 ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
67 @@ -315,9 +306,9 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
69 static u32 rtl9300_i2c_func(struct i2c_adapter *a)
71 - return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
72 - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
73 - I2C_FUNC_SMBUS_BLOCK_DATA;
74 + return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
75 + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
76 + I2C_FUNC_SMBUS_I2C_BLOCK;
79 static const struct i2c_algorithm rtl9300_i2c_algo = {